home *** CD-ROM | disk | FTP | other *** search
- #define LIBQTOOLS_CORE
- #define LIBQBUILD_CORE
- #include "../include/libqtools.h"
- #include "../include/libqbuild.h"
-
- /*
- * modelgen.c: generates a .mdl file from a base triangle file (.tri), a
- * texture containing front and back skins (.lbm), and a series of frame
- * triangle files (.tri). Result is stored in
- * /raid/quake/models/<scriptname>.mdl.
- */
-
- struct mdlheader model;
-
- char file1[1024];
- char skinname[1024];
- char qbasename[1024];
- float scale, scale_up = 1.0;
- vec3_t mins, maxs;
- vec3_t framesmins, framesmaxs;
- vec3_t adjust;
-
- /*
- * base frame info
- */
-
- char cdpartial[256];
- char cddir[256];
-
- bool cdset;
- int degeneratetris;
- int firstframe = 1;
- float totsize, averagesize;
-
- #define NUMVERTEXNORMALS 162
-
- float avertexnormals[NUMVERTEXNORMALS][3] =
- {
- #include "anorms.h"
- };
-
- char outname[1024];
-
- /*============================================================================ */
-
- void ClearModel(void)
- {
- __bzero(&model, sizeof(model));
- model.synctype = ST_RAND; /* default */
-
- bspMem->numframes = bspMem->numskins = 0;
-
- scale = 0;
- scale_up = 1.0;
-
- VectorCopy(vec3_origin, adjust);
- VectorCopy(vec3_origin, mins);
- VectorCopy(vec3_origin, maxs);
- VectorCopy(vec3_origin, framesmins);
- VectorCopy(vec3_origin, framesmaxs);
-
- degeneratetris = 0;
- cdset = false;
- firstframe = 1;
- totsize = 0.0;
- }
-
- /*
- * ============
- * WriteFrame
- * ============
- */
- void WriteFrame(HANDLE modelouthandle, int framenum)
- {
- int j, k;
- struct trivert *pframe;
- struct daliasframe aframe;
- float v;
-
- pframe = bspMem->verts[framenum];
-
- strcpy(aframe.name, bspMem->frames[framenum].name);
-
- for (j = 0; j < 3; j++) {
- aframe.bboxmin.v[j] = 255;
- aframe.bboxmax.v[j] = 0;
- }
-
- for (j = 0; j < model.numverts; j++) {
- /* all of these are byte values, so no need to deal with endianness */
- bspMem->tarray[j].lightnormalindex = pframe[j].lightnormalindex;
-
- if (bspMem->tarray[j].lightnormalindex > NUMVERTEXNORMALS)
- Error("invalid lightnormalindex %d\n", bspMem->tarray[j].lightnormalindex);
-
- for (k = 0; k < 3; k++) {
- /* scale to byte values & min/max check */
- v = (pframe[j].v[k] - model.scale_origin[k]) / model.scale[k];
-
- bspMem->tarray[j].v[k] = v;
-
- if (bspMem->tarray[j].v[k] < aframe.bboxmin.v[k]) {
- aframe.bboxmin.v[k] = bspMem->tarray[j].v[k];
- }
- if (bspMem->tarray[j].v[k] > aframe.bboxmax.v[k]) {
- aframe.bboxmax.v[k] = bspMem->tarray[j].v[k];
- }
-
- }
- }
-
- __write(modelouthandle, &aframe, sizeof(aframe));
- __write(modelouthandle, &bspMem->tarray[0], model.numverts * sizeof(bspMem->tarray[0]));
- }
-
- /*
- * ============
- * WriteGroupBBox
- * ============
- */
- void WriteGroupBBox(HANDLE modelouthandle, int numframes, int curframe)
- {
- int i, j, k;
- struct daliasgroup dagroup;
- struct trivert *pframe;
-
- dagroup.numframes = LittleLong(numframes);
-
- for (i = 0; i < 3; i++) {
- dagroup.bboxmin.v[i] = 255;
- dagroup.bboxmax.v[i] = 0;
- }
-
- for (i = 0; i < numframes; i++) {
- pframe = (struct trivert *)bspMem->frames[curframe].pdata;
-
- for (j = 0; j < model.numverts; j++) {
- for (k = 0; k < 3; k++) {
- /* scale to byte values & min/max check */
- bspMem->tarray[j].v[k] = (pframe[j].v[k] - model.scale_origin[k]) /
- model.scale[k];
- if (bspMem->tarray[j].v[k] < dagroup.bboxmin.v[k])
- dagroup.bboxmin.v[k] = bspMem->tarray[j].v[k];
- if (bspMem->tarray[j].v[k] > dagroup.bboxmax.v[k])
- dagroup.bboxmax.v[k] = bspMem->tarray[j].v[k];
- }
- }
-
- curframe++;
- }
-
- __write(modelouthandle, &dagroup, sizeof(dagroup));
- }
-
- /*
- * ============
- * WriteModel
- * ============
- */
- bool WriteModelFile(HANDLE modelouthandle)
- {
- int i, curframe, curskin;
- float dist[3];
- struct mdlheader modeltemp;
-
- /* Calculate the bounding box for this model */
- for (i = 0; i < 3; i++) {
- mprintf("framesmins[%d]: %f, framesmaxs[%d]: %f\n", i, framesmins[i], i, framesmaxs[i]);
- if (fabs(framesmins[i]) > fabs(framesmaxs[i]))
- dist[i] = framesmins[i];
- else
- dist[i] = framesmaxs[i];
-
- model.scale[i] = (framesmaxs[i] - framesmins[i]) / 255.9;
- model.scale_origin[i] = framesmins[i];
- }
-
- model.boundingradius = VectorLength(dist);
-
- /*
- * write out the model header
- */
- modeltemp.ident = LittleLong(MAGIC_MDL_Q1);
- modeltemp.version = LittleLong(MDL_VERSION);
- modeltemp.boundingradius = LittleFloat(model.boundingradius);
-
- for (i = 0; i < 3; i++) {
- modeltemp.scale[i] = LittleFloat(model.scale[i]);
- modeltemp.scale_origin[i] = LittleFloat(model.scale_origin[i]);
- modeltemp.eyeposition[i] = LittleFloat(model.eyeposition[i] + adjust[i]);
- }
-
- modeltemp.flags = LittleLong(model.flags);
- modeltemp.numskins = LittleLong(model.numskins);
- modeltemp.skinwidth = LittleLong(model.skinwidth);
- modeltemp.skinheight = LittleLong(model.skinheight);
- modeltemp.numverts = LittleLong(model.numverts);
- modeltemp.numtris = LittleLong(model.numtris - degeneratetris);
- modeltemp.numframes = LittleLong(model.numframes);
- modeltemp.synctype = LittleFloat(model.synctype);
- averagesize = totsize / model.numtris;
- modeltemp.size = LittleFloat(averagesize);
-
- __write(modelouthandle, &modeltemp, sizeof(model));
-
- /*
- * write out the skins
- */
- curskin = 0;
-
- for (i = 0; i < model.numskins; i++) {
- __write(modelouthandle, &bspMem->skins[curskin].type, sizeof(bspMem->skins[curskin].type));
- __write(modelouthandle, bspMem->skins[curskin].pdata, model.skinwidth * model.skinheight);
- curskin++;
- }
-
- /*
- * write out the base model (the s & t coordinates for the vertices)
- */
- for (i = 0; i < model.numverts; i++) {
- if (bspMem->stverts[i].onseam == 3) {
- bspMem->stverts[i].onseam = LittleLong(MDL_ONSEAM);
- }
- else {
- bspMem->stverts[i].onseam = LittleLong(0);
- }
-
- bspMem->stverts[i].s = LittleLong(bspMem->stverts[i].s);
- bspMem->stverts[i].t = LittleLong(bspMem->stverts[i].t);
- }
-
- __write(modelouthandle, bspMem->stverts, model.numverts * sizeof(bspMem->stverts[0]));
-
- /*
- * write out the triangles
- */
- for (i = 0; i < model.numtris; i++) {
- int j;
- struct dtriangle tri;
-
- if (!bspMem->degenerate[i]) {
- tri.facesfront = LittleLong(bspMem->triangles[i].facesfront);
-
- for (j = 0; j < 3; j++) {
- tri.vertindex[j] = LittleLong(bspMem->triangles[i].vertindex[j]);
- }
- __write(modelouthandle, &tri, sizeof(tri));
- }
- }
-
- /*
- * write out the frames
- */
- curframe = 0;
-
- for (i = 0; i < model.numframes; i++) {
- __write(modelouthandle, &bspMem->frames[curframe].type, sizeof(bspMem->frames[curframe].type));
-
- if (bspMem->frames[curframe].type == MDL_SINGLE) {
- /* single (non-grouped) frame */
- WriteFrame(modelouthandle, curframe);
- curframe++;
- }
- else {
- int j, numframes, groupframe;
- float totinterval;
-
- groupframe = curframe;
- curframe++;
- numframes = bspMem->frames[groupframe].numgroupframes;
-
- /* set and write the group header */
- WriteGroupBBox(modelouthandle, numframes, curframe);
-
- /* write the interval array */
- totinterval = 0.0;
-
- for (j = 0; j < numframes; j++) {
- daliasinterval_t temp;
-
- totinterval += bspMem->frames[groupframe + 1 + j].interval;
- temp.interval = LittleFloat(totinterval);
-
- __write(modelouthandle, &temp, sizeof(temp));
- }
-
- for (j = 0; j < numframes; j++) {
- WriteFrame(modelouthandle, curframe);
- curframe++;
- }
- }
- }
-
- return TRUE;
- }
-
- /*
- * ===============
- * WriteModel
- * ===============
- */
- bool WriteModel(void)
- {
- HANDLE modelouthandle;
- bool success = FALSE;
-
- /* write the model output file */
- if (!bspMem->numframes) {
- eprintf("no frames grabbed, no file generated\n");
- }
- else {
- if (bspMem->numskins) {
- ReplaceExt(outname, "mdl");
-
- mprintf("---------------------\n");
- mprintf("writing %s:\n", outname);
- if((modelouthandle = __open(outname, H_WRITE_BINARY)) > 0) {
- if(WriteModelFile(modelouthandle)) {
- mprintf("%4d frame(s)\n", model.numframes);
- mprintf("%4d ungrouped frame(s), including group headers\n", bspMem->numframes);
- mprintf("%4d skin(s)\n", model.numskins);
- mprintf("%4d degenerate triangles(s) removed\n", degeneratetris);
- mprintf("%4d triangles emitted\n", model.numtris - degeneratetris);
- mprintf("pixels per triangle %f\n", averagesize);
-
- mprintf("file size: %d\n", (int)ftell(modelouthandle));
- mprintf("---------------------\n");
- success = TRUE;
- }
- else
- eprintf("failed to save model to %s\n", outname);
- __close(modelouthandle);
-
- ClearModel();
- }
- else
- eprintf("failed to open file %s\n", outname);
- }
- else
- eprintf("frames with no skins\n");
- }
-
- return success;
- }
-
- /*
- * ============
- * SetSkinValues
- *
- * Called for the base frame
- * ============
- */
- void SetSkinValues(void)
- {
- int i;
- float v;
- int width, height, iwidth, iheight, skinwidth;
- float basex, basey;
-
- for (i = 0; i < 3; i++) {
- mins[i] = 9999999;
- maxs[i] = -9999999;
- }
-
- for (i = 0; i < model.numverts; i++) {
- int j;
-
- bspMem->stverts[i].onseam = 0;
-
- for (j = 0; j < 3; j++) {
- v = bspMem->baseverts[i][j];
- if (v < mins[j])
- mins[j] = v;
- if (v > maxs[j])
- maxs[j] = v;
- }
- }
-
- for (i = 0; i < 3; i++) {
- mins[i] = floor(mins[i]);
- maxs[i] = ceil(maxs[i]);
- }
-
- width = maxs[0] - mins[0];
- height = maxs[2] - mins[2];
-
- mprintf("width: %i height: %i\n", width, height);
-
- scale = 8;
- if (width * scale >= 150)
- scale = 150.0 / width;
- if (height * scale >= 190)
- scale = 190.0 / height;
- iwidth = ceil(width * scale) + 4;
- iheight = ceil(height * scale) + 4;
-
- mprintf("scale: %f\n", scale);
- mprintf("iwidth: %i iheight: %i\n", iwidth, iheight);
-
- /* determine which side of each triangle to map the texture to */
- for (i = 0; i < model.numtris; i++) {
- int j;
- vec3_t vtemp1, vtemp2, normal;
-
- VectorSubtract(bspMem->baseverts[bspMem->triangles[i].vertindex[0]], bspMem->baseverts[bspMem->triangles[i].vertindex[1]], vtemp1);
- VectorSubtract(bspMem->baseverts[bspMem->triangles[i].vertindex[2]], bspMem->baseverts[bspMem->triangles[i].vertindex[1]], vtemp2);
- CrossProduct(vtemp1, vtemp2, normal);
-
- if (normal[1] > 0) {
- basex = iwidth + 2;
- bspMem->triangles[i].facesfront = 0;
- }
- else {
- basex = 2;
- bspMem->triangles[i].facesfront = 1;
- }
- basey = 2;
-
- for (j = 0; j < 3; j++) {
- float *pbasevert;
- struct stvert *pstvert;
-
- pbasevert = bspMem->baseverts[bspMem->triangles[i].vertindex[j]];
- pstvert = &bspMem->stverts[bspMem->triangles[i].vertindex[j]];
-
- if (bspMem->triangles[i].facesfront) {
- pstvert->onseam |= 1;
- }
- else {
- pstvert->onseam |= 2;
- }
-
- if ((bspMem->triangles[i].facesfront) || ((pstvert->onseam & 1) == 0)) {
- /* we want the front s value for seam vertices */
- pstvert->s = rint((pbasevert[0] - mins[0]) * scale + basex);
- pstvert->t = rint((maxs[2] - pbasevert[2]) * scale + basey);
- }
- }
- }
-
- /*
- * make the width a multiple of 4; some hardware requires this, and it ensures
- * dword alignment for each scan
- */
- skinwidth = iwidth * 2;
- model.skinwidth = (skinwidth + 3) & ~3;
- model.skinheight = iheight;
-
- mprintf("skin width: %i (unpadded width %i) skin height: %i\n",
- model.skinwidth, skinwidth, model.skinheight);
- }
-
- /*
- * =================
- * Cmd_Base
- * =================
- */
- void Cmd_Base(void)
- {
- struct triangle *ptri;
- int i, j, k;
- int time1;
-
- GetToken(false);
- strcpy(qbasename, token);
- sprintf(file1, "%s/%s.tri", cdpartial, token);
-
- ExpandPathAndArchive(file1);
-
- sprintf(file1, "%s/%s.tri", cddir, token);
- time1 = FileTime(file1);
- if (time1 == -1)
- Error("%s doesn't exist", file1);
-
- /* load the base triangles */
- LoadTriangleList(file1, &ptri, &model.numtris);
- mprintf("NUMBER OF TRIANGLES (including degenerate triangles): %d\n", model.numtris);
-
- /*
- * run through all the base triangles, storing each unique vertex in the
- * base vertex list and setting the indirect triangles to point to the base
- * vertices
- */
- for (i = 0; i < model.numtris; i++) {
- if (VectorCompare(ptri[i].verts[0], ptri[i].verts[1]) ||
- VectorCompare(ptri[i].verts[1], ptri[i].verts[2]) ||
- VectorCompare(ptri[i].verts[2], ptri[i].verts[0])) {
- degeneratetris++;
- bspMem->degenerate[i] = 1;
- }
- else {
- bspMem->degenerate[i] = 0;
- }
-
- for (j = 0; j < 3; j++) {
- for (k = 0; k < model.numverts; k++)
- if (VectorCompare(ptri[i].verts[j], bspMem->baseverts[k]))
- break; /* this vertex is already in the base vertex list */
-
- if (k == model.numverts) {
- /* new vertex */
- VectorCopy(ptri[i].verts[j], bspMem->baseverts[model.numverts]);
- model.numverts++;
- }
-
- bspMem->triangles[i].vertindex[j] = k;
- }
- }
-
- mprintf("NUMBER OF VERTEXES: %i\n", model.numverts);
-
- /* calculate s & t for each vertex, and set the skin width and height */
- SetSkinValues();
- }
-
- /*
- * ===============
- * Cmd_Skin
- * ===============
- */
- void Cmd_Skin(void)
- {
- struct palpic *pskinbitmap;
- byte *ptemp1, *ptemp2;
- int i;
- int time1;
-
- GetToken(false);
- strcpy(skinname, token);
- sprintf(file1, "%s/%s.lbm", cdpartial, token);
-
- ExpandPathAndArchive(file1);
-
- sprintf(file1, "%s/%s.lbm", cddir, token);
- time1 = FileTime(file1);
- if (time1 == -1)
- Error("%s not found", file1);
-
- if (TokenAvailable()) {
- GetToken(false);
- bspMem->skins[bspMem->numskins].interval = atof(token);
- if (bspMem->skins[bspMem->numskins].interval <= 0.0)
- Error("Non-positive interval");
- }
- else {
- bspMem->skins[bspMem->numskins].interval = 0.1;
- }
-
- /* load in the skin file */
- pskinbitmap = GetImage(file1, 0, -model.skinwidth, -model.skinheight);
-
- /*
- * now copy the part of the texture we care about, since LBMs are always
- * loaded as 320x200 bitmaps
- */
- bspMem->skins[bspMem->numskins].pdata = tmalloc(model.skinwidth * model.skinheight);
-
- if (!bspMem->skins[bspMem->numskins].pdata)
- Error("couldn't get memory for skin texture");
-
- ptemp1 = bspMem->skins[bspMem->numskins].pdata;
- ptemp2 = pskinbitmap;
-
- for (i = 0; i < model.skinheight; i++) {
- __memcpy(ptemp1, ptemp2, model.skinwidth);
- ptemp1 += model.skinwidth;
- ptemp2 += 320;
- }
-
- if (bspMem->numskins >= bspMem->max_numskins)
- EpandClusters(bspMem, MODEL_SKINS);
- bspMem->numskins++;
- }
-
- /*
- * ===============
- * GrabFrame
- * ===============
- */
- void GrabFrame(char *frame, int isgroup)
- {
- struct triangle *ptri;
- int i, j;
- struct trivert *ptrivert;
- int numtris;
- int time1;
-
- sprintf(file1, "%s/%s.tri", cdpartial, frame);
- ExpandPathAndArchive(file1);
-
- sprintf(file1, "%s/%s.tri", cddir, frame);
- time1 = FileTime(file1);
- if (time1 == -1)
- Error("%s does not exist", file1);
-
- mprintf("grabbing %s\n", file1);
- bspMem->frames[bspMem->numframes].interval = 0.1;
- strcpy(bspMem->frames[bspMem->numframes].name, frame);
-
- /* load the frame */
- LoadTriangleList(file1, &ptri, &numtris);
-
- if (numtris != model.numtris)
- Error("number of triangles doesn't match\n");
-
- /* set the intervals */
- if (isgroup && TokenAvailable()) {
- GetToken(false);
- bspMem->frames[bspMem->numframes].interval = atof(token);
- if (bspMem->frames[bspMem->numframes].interval <= 0.0)
- Error("Non-positive interval %s %f", token, bspMem->frames[bspMem->numframes].interval);
- }
- else {
- bspMem->frames[bspMem->numframes].interval = 0.1;
- }
-
- /* allocate storage for the frame's vertices */
- ptrivert = bspMem->verts[bspMem->numframes];
-
- bspMem->frames[bspMem->numframes].pdata = ptrivert;
- bspMem->frames[bspMem->numframes].type = MDL_SINGLE;
-
- for (i = 0; i < model.numverts; i++) {
- bspMem->vnorms[i].numnormals = 0;
- }
-
- /*
- * store the frame's vertices in the same order as the base. This assumes the
- * triangles and vertices in this frame are in exactly the same order as in the
- * base
- */
- for (i = 0; i < numtris; i++) {
- vec3_t vtemp1, vtemp2, normal;
- float ftemp;
-
- if (bspMem->degenerate[i])
- continue;
-
- if (firstframe) {
- VectorSubtract(ptri[i].verts[0], ptri[i].verts[1], vtemp1);
- VectorSubtract(ptri[i].verts[2], ptri[i].verts[1], vtemp2);
- VectorScale(vtemp1, scale_up, vtemp1);
- VectorScale(vtemp2, scale_up, vtemp2);
- CrossProduct(vtemp1, vtemp2, normal);
-
- totsize += VectorLength(normal) / 2.0;
- }
-
- VectorSubtract(ptri[i].verts[0], ptri[i].verts[1], vtemp1);
- VectorSubtract(ptri[i].verts[2], ptri[i].verts[1], vtemp2);
- CrossProduct(vtemp1, vtemp2, normal);
-
- VectorNormalize(normal);
-
- /* rotate the normal so the model faces down the positive x axis */
- ftemp = normal[0];
- normal[0] = -normal[1];
- normal[1] = ftemp;
-
- for (j = 0; j < 3; j++) {
- int k;
- int vertindex;
-
- vertindex = bspMem->triangles[i].vertindex[j];
-
- /*
- * rotate the vertices so the model faces down the positive x axis
- * also adjust the vertices to the desired origin
- */
- ptrivert[vertindex].v[0] = ((-ptri[i].verts[j][1]) * scale_up) + adjust[0];
- ptrivert[vertindex].v[1] = (ptri[i].verts[j][0] * scale_up) + adjust[1];
- ptrivert[vertindex].v[2] = (ptri[i].verts[j][2] * scale_up) + adjust[2];
-
- for (k = 0; k < 3; k++) {
- if (ptrivert[vertindex].v[k] < framesmins[k])
- framesmins[k] = ptrivert[vertindex].v[k];
-
- if (ptrivert[vertindex].v[k] > framesmaxs[k])
- framesmaxs[k] = ptrivert[vertindex].v[k];
- }
-
- VectorCopy(normal, bspMem->vnorms[vertindex].normals[bspMem->vnorms[vertindex].numnormals]);
- bspMem->vnorms[vertindex].numnormals++;
- }
- }
-
- /*
- * calculate the vertex normals, match them to the template list, and store the
- * index of the best match
- */
- for (i = 0; i < model.numverts; i++) {
- int j;
- vec3_t v;
- float maxdot;
- int maxdotindex;
-
- if (bspMem->vnorms[i].numnormals > 0) {
- for (j = 0; j < 3; j++) {
- int k;
-
- v[j] = 0;
-
- for (k = 0; k < bspMem->vnorms[i].numnormals; k++) {
- v[j] += bspMem->vnorms[i].normals[k][j];
- }
-
- v[j] /= bspMem->vnorms[i].numnormals;
- }
- }
- else {
- Error("Vertex with no non-degenerate triangles attached");
- }
-
- VectorNormalize(v);
-
- maxdot = -999999.0;
- maxdotindex = -1;
-
- for (j = 0; j < NUMVERTEXNORMALS; j++) {
- float dot;
-
- dot = DotProduct(v, avertexnormals[j]);
- if (dot > maxdot) {
- maxdot = dot;
- maxdotindex = j;
- }
- }
-
- ptrivert[i].lightnormalindex = maxdotindex;
- }
-
- if (bspMem->numframes >= bspMem->max_numframes)
- EpandClusters(bspMem, MODEL_FRAMES);
- bspMem->numframes++;
-
- tfree(ptri);
- firstframe = 0;
- }
-
- /*
- * ===============
- * Cmd_Frame
- * ===============
- */
- void Cmd_Frame(int isgroup)
- {
- while (TokenAvailable()) {
- GetToken(false);
- GrabFrame(token, isgroup);
-
- if (!isgroup)
- model.numframes++;
- }
- }
-
- /*
- * ===============
- * Cmd_SkinGroupStart
- * ===============
- */
- void Cmd_SkinGroupStart(void)
- {
- int groupskin;
-
- if (bspMem->numskins >= bspMem->max_numskins)
- EpandClusters(bspMem, MODEL_SKINS);
- groupskin = bspMem->numskins++;
-
- bspMem->skins[groupskin].type = MDL_SKIN_GROUP;
- bspMem->skins[groupskin].numgroupskins = 0;
-
- while (1) {
- GetToken(true);
- if (endofscript)
- Error("End of file during group");
-
- if (!strcmp(token, "$skin")) {
- Cmd_Skin();
- bspMem->skins[groupskin].numgroupskins++;
- }
- else if (!strcmp(token, "$skingroupend")) {
- break;
- }
- else {
- Error("$skin or $skingroupend expected\n");
- }
-
- }
-
- if (bspMem->skins[groupskin].numgroupskins == 0)
- Error("Empty group\n");
- }
-
- /*
- * ===============
- * Cmd_FrameGroupStart
- * ===============
- */
- void Cmd_FrameGroupStart(void)
- {
- int groupframe;
-
- if (bspMem->numframes >= bspMem->max_numframes)
- EpandClusters(bspMem, MODEL_FRAMES);
- groupframe = bspMem->numframes++;
-
- bspMem->frames[groupframe].type = MDL_GROUP;
- bspMem->frames[groupframe].numgroupframes = 0;
-
- while (1) {
- GetToken(true);
- if (endofscript)
- Error("End of file during group");
-
- if (!strcmp(token, "$frame")) {
- Cmd_Frame(1);
- }
- else if (!strcmp(token, "$framegroupend")) {
- break;
- }
- else {
- Error("$frame or $framegroupend expected\n");
- }
-
- }
-
- bspMem->frames[groupframe].numgroupframes += bspMem->numframes - groupframe - 1;
-
- if (bspMem->frames[groupframe].numgroupframes == 0)
- Error("Empty group\n");
- }
-
- /*
- * =================
- * Cmd_Origin
- * =================
- */
- void Cmd_Origin(void)
- {
- /*
- * rotate points into frame of reference so model points down the positive x
- * axis
- */
- GetToken(false);
- adjust[1] = -atof(token);
-
- GetToken(false);
- adjust[0] = atof(token);
-
- GetToken(false);
- adjust[2] = -atof(token);
- }
-
- /*
- * =================
- * Cmd_Eyeposition
- * =================
- */
- void Cmd_Eyeposition(void)
- {
- /*
- * rotate points into frame of reference so model points down the positive x
- * axis
- */
- GetToken(false);
- model.eyeposition[1] = atof(token);
-
- GetToken(false);
- model.eyeposition[0] = -atof(token);
-
- GetToken(false);
- model.eyeposition[2] = atof(token);
- }
-
- /*
- * =================
- * Cmd_ScaleUp
- * =================
- */
- void Cmd_ScaleUp(void)
- {
- GetToken(false);
- scale_up = atof(token);
- }
-
- /*
- * =================
- * Cmd_Flags
- * =================
- */
- void Cmd_Flags(void)
- {
- GetToken(false);
- model.flags = atoi(token);
- }
-
- /*
- * =================
- * Cmd_Modelname
- * =================
- */
- void Cmd_Modelname(void)
- {
- WriteModel();
- GetToken(false);
- strcpy(outname, token);
- }
-
- /*
- * ===============
- * ParseScript
- * ===============
- */
- void ParseScript(void)
- {
- while (1) {
- do { /* look for a line starting with a $ command */
- GetToken(true);
- if (endofscript)
- return;
- if (token[0] == '$')
- break;
- while (TokenAvailable())
- GetToken(false);
- } while (1);
-
- if (!strcmp(token, "$modelname")) {
- Cmd_Modelname();
- }
- else if (!strcmp(token, "$base")) {
- Cmd_Base();
- }
- else if (!strcmp(token, "$cd")) {
- if (cdset)
- Error("Two $cd in one model");
- cdset = true;
- GetToken(false);
- strcpy(cdpartial, token);
-
- strcpy(cddir, ExpandPath(token));
-
- }
- else if (!strcmp(token, "$sync")) {
- model.synctype = ST_SYNC;
- }
- else if (!strcmp(token, "$origin")) {
- Cmd_Origin();
- }
- else if (!strcmp(token, "$eyeposition")) {
- Cmd_Eyeposition();
- }
- else if (!strcmp(token, "$scale")) {
- Cmd_ScaleUp();
- }
- else if (!strcmp(token, "$flags")) {
- Cmd_Flags();
- }
- else if (!strcmp(token, "$frame")) {
- Cmd_Frame(0);
- }
- else if (!strcmp(token, "$skin")) {
- Cmd_Skin();
- model.numskins++;
- }
- else if (!strcmp(token, "$framegroupstart")) {
- Cmd_FrameGroupStart();
- model.numframes++;
- }
- else if (!strcmp(token, "$skingroupstart")) {
- Cmd_SkinGroupStart();
- model.numskins++;
- }
- else {
- Error("bad command %s\n", token);
- }
- }
- }
-
- /*
- * ==============
- * main
- * ==============
- */
- int main(int argc, char **argv)
- {
- int i;
- char path[1024];
-
- if (argc != 2 && argc != 4)
- Error("usage: modelgen [-archive directory] file.qc");
-
- if (!strcmp(argv[1], "-archive")) {
- archive = true;
- strcpy(archivedir, argv[2]);
- mprintf("Archiving source to: %s\n", archivedir);
- i = 3;
- }
- else
- i = 1;
-
- /*
- * load the script
- */
- strcpy(path, argv[i]);
-
- DefaultExtension(path, ".qc");
- SetQdirFromPath(path);
-
- LoadScriptFile(path);
-
- /*
- * parse it
- */
- __bzero(&model, sizeof(model));
-
- for (i = 0; i < 3; i++) {
- framesmins[i] = 9999999;
- framesmaxs[i] = -9999999;
- }
-
- ClearModel();
- strcpy(outname, argv[1]);
-
- ParseScript();
- WriteModel();
-
- return 0;
- }
-